package com.tansun.ruledata.data.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tansun.rule.pojo.EnterPoint;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.MField;
import com.tansun.ruledata.data.dao.RuleDeployVersionDao;
import com.tansun.ruledata.data.dao.RuleDeployFlowParamDao;
import com.tansun.ruledata.data.dao.RuleLatestVersionDao;
import com.tansun.ruledata.data.entity.DeployDatacomponent;
import com.tansun.ruledata.data.entity.DeployFlowRect;
import com.tansun.ruledata.data.entity.DeployReferenceData;
import com.tansun.ruledata.data.entity.DeployReleModel;
import com.tansun.ruledata.data.entity.DeployVersionInfo;
import com.tansun.ruledata.data.model.ProjectInfo;
import com.tansun.ruledata.data.service.RuleFlowService;

@Service
public class RuleFlowServiceImpl implements RuleFlowService {

	@Autowired
	private RuleDeployVersionDao ruleDeployVersionDAO;

	@Autowired
	private RuleLatestVersionDao ruleLatestVersionDao;
	@Autowired
	private RuleDeployFlowParamDao ruleFlowParamDao;

	@Override
	public Map<String, MClass> findDeployRuleFlowParam(String projectCode, String invokePoint,
			Map<String, MClass> paramMap, Map<String, MClass> metaMap) {
		Map<String, Object> qMap = new HashMap<>();
		qMap.put("projectCode", projectCode);
		qMap.put("invokePoint", invokePoint);
		qMap.put("statusInd", "1");
		List<EnterPoint> list = this.ruleDeployVersionDAO.findEnterPoint(qMap);
		String refId = null;
		for (EnterPoint enterPoint : list) {
			refId = enterPoint.getRuleflowId();
			if (StringUtils.isEmpty(refId))
				continue;
			this.findRuleFlowParam(projectCode, refId, paramMap, metaMap);
		}
		return paramMap;
	}

	@Override
	public Map<String, MClass> findRuleFlowParam(String projectCode, String code, Map<String, MClass> paramMap,
			Map<String, MClass> metaMap) {
		ProjectInfo projectInfo = new ProjectInfo();
		projectInfo.setProjectCode(projectCode);
		projectInfo.setCode(code);
		List<DeployFlowRect> list = this.ruleLatestVersionDao.findRuleFlowRect(projectInfo);
		for (DeployFlowRect flowRect : list) {
			String rectType = flowRect.getRectType();
			String rcode = flowRect.getRectCode();
			// String blockVersion = flowRect.getActiveVersion();
			if (rcode == null)
				continue;
			this.findRefParam(rcode, projectCode, paramMap, metaMap);
			if ("decisionTree".equals(rectType)) {

				this.findRefModelInfo(projectCode, rcode, paramMap, metaMap);
			}

			if ("ruleFlow".equals(rectType) || "strategyFlow".equals(rectType)) {
				this.findRuleFlowParam(projectCode, rcode, paramMap, metaMap);
			}

			if ("executionblock".equals(rectType.toLowerCase())) {
				Map<String, Object> queryMap = new HashMap<>();
				queryMap.put("projectCode", projectCode);
				queryMap.put("code", rcode);
				List<DeployVersionInfo> blist = this.ruleLatestVersionDao.findRuleExcutionBlock(queryMap);
				for (DeployVersionInfo ruleVer : blist) {
					String ecode = ruleVer.getModelCode();
					this.findRefParam(ecode, projectCode, paramMap, metaMap);
				}

			}
		}
		return paramMap;

	}

	private void findRefModelInfo(String projectCode, String rectCode, Map<String, MClass> paramMap,
			Map<String, MClass> metaMap) {
		ProjectInfo projectInfo = new ProjectInfo();
		projectInfo.setProjectCode(projectCode);
		projectInfo.setCode(rectCode);
		List<DeployReleModel> list = this.ruleFlowParamDao.findRuleReleModel(projectInfo);
		if (list != null) {
			for (DeployReleModel releModel : list) {
				String refe_code = releModel.getRefeCode();
//		    	 String  model_type =releModel.getModelType();
				this.findRefParam(refe_code, projectCode, paramMap, metaMap);
			}
		}
	}

	private void findRefParam(String code, String projectCode, Map<String, MClass> paramMap,
			Map<String, MClass> metaMap) {
		ProjectInfo projectInfo = new ProjectInfo();
		projectInfo.setProjectCode(projectCode);
		projectInfo.setCode(code);
		List<DeployReferenceData> list = this.ruleFlowParamDao.findRuleModelRefParam(projectInfo);
		MClass mClass = null;
		MClass tmpClass = null;
		for (DeployReferenceData refData : list) {
			String className = refData.getClassName();
			String nameEn = refData.getNameen();
			mClass = paramMap.get(className);
			tmpClass = metaMap.get(className);
			if (tmpClass == null) {
				continue;
			}
			if (mClass == null) {
				mClass = new MClass();
				mClass.setName(tmpClass.getName());
				mClass.setParamType(tmpClass.getParamType());
				mClass.setChzn(tmpClass.getChzn());
				mClass.setFieldMap(tmpClass.getFieldMap());
				mClass.setmFieldNames(null);

				mClass.setParams(new ArrayList<MField>());
				paramMap.put(className, mClass);
			}
			MField field = tmpClass.getFieldMap().get(nameEn);
			if (field == null)
				continue;
			MField newField = new MField();
			try {
				BeanUtils.copyProperties(newField, field);
			} catch (Exception e) {
				e.printStackTrace();
			}
			newField.setParamFor(refData.getContentType());
			if (!isExistsParam(mClass.getParams(), newField)) {
				mClass.getParams().add(newField);
			}
		}
	}

	private boolean isExistsParam(List<MField> params, MField newField) {
		if (params == null || params.size() == 0 || params.isEmpty())
			return false;
		for (MField mField : params) {
			if (newField.getName() == mField.getName()) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	public List<DeployDatacomponent>  findDataComponet(String  projectCode,String invokePoint){
	   	 List<DeployDatacomponent>  result  = new  ArrayList<>();
			Map<String, Object> qMap = new HashMap<>();
			qMap.put("projectCode", projectCode);
			qMap.put("invokePoint", invokePoint);
	    List<EnterPoint>  list =	 this.ruleDeployVersionDAO.findEnterPoint(qMap);
  		 String   refId ="";
	    for (EnterPoint enterPoint :list) {
	    	refId = enterPoint.getDatacomponentids();
	    	String[] ruleflowinfo = refId.split(",");
		   	
  			 if (ruleflowinfo == null && ruleflowinfo.length<1){
  				 continue;
  			 }
  			 
  			List<DeployDatacomponent> daList = this.ruleFlowParamDao.findRuleDatacomponent(ruleflowinfo);
  			for (DeployDatacomponent rcomDatacomponent : daList) {
  				result.add(rcomDatacomponent);
  			}
	    	
	    }
	    return  result;
	   	 
	}   	 
}
